/*
 * Copyright 2024 The CHANGLEI Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/// 像素转换库
library px;

import 'dart:math' as math;
import 'dart:typed_data';
import 'dart:ui';

import 'package:flutter/widgets.dart';

part 'src/math.dart';
part 'src/px.dart';
part 'src/px_offset.dart';
part 'src/px_r_rect.dart';
part 'src/px_r_s_transform.dart';
part 'src/px_radius.dart';
part 'src/px_rect.dart';
part 'src/px_size.dart';

/// 获取当前设备的像素密度
extension on BuildContext {
  /// 获取当前设备的像素密度
  double get density => MediaQuery.devicePixelRatioOf(this);
}

abstract class _Px<T> {
  /// toDp
  T toDp(BuildContext context);
}

PxDouble _lerpPxDouble(PxDouble a, PxDouble b, double t) {
  return a * (1.0 - t).px + b * t.px;
}

/// See [OffsetBase]
abstract class PxOffsetBase {
  /// See [OffsetBase.new]
  const PxOffsetBase(this._dx, this._dy);

  final PxDouble _dx;
  final PxDouble _dy;

  /// See [OffsetBase.isInfinite]
  bool get isInfinite => _dx >= PxDouble.infinity || _dy >= PxDouble.infinity;

  /// See [OffsetBase.isFinite]
  bool get isFinite => _dx.isFinite && _dy.isFinite;

  /// See [OffsetBase.<]
  bool operator <(PxOffsetBase other) => _dx < other._dx && _dy < other._dy;

  /// See [OffsetBase.<=]
  bool operator <=(PxOffsetBase other) => _dx <= other._dx && _dy <= other._dy;

  /// See [OffsetBase.>]
  bool operator >(PxOffsetBase other) => _dx > other._dx && _dy > other._dy;

  /// See [OffsetBase.>=]
  bool operator >=(PxOffsetBase other) => _dx >= other._dx && _dy >= other._dy;

  @override
  bool operator ==(Object other) {
    return other is PxOffsetBase && other._dx == _dx && other._dy == _dy;
  }

  @override
  int get hashCode => Object.hash(_dx, _dy);

  @override
  String toString() => 'PxOffsetBase(${_dx.toStringAsFixed(1)}, ${_dy.toStringAsFixed(1)})';
}
